use bincode;
use serde::{Deserialize, Serialize};
use crypto::digest::Digest;
use crypto::sha3::Sha3;

// https://docs.rs/bincode/1.3.1/bincode/fn.serialize.html
// pub fn serialize<T: ?Sized>(value: &T) -> Result<Vec<u8>>
//     where
//         T: Serialize,
pub fn my_serialize<T: ?Sized>(value: &T) -> Vec<u8>
    where T: Serialize
{
    let serialized = bincode::serialize(value).unwrap();
    serialized
}

// https://docs.rs/bincode/1.3.1/bincode/fn.deserialize.html
// pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result<T>
//     where
//         T: Deserialize<'a>,
pub fn my_deserialize<'a, T>(bytes: &'a [u8]) -> T
    where T: Deserialize<'a>
{
    let deserialize = bincode::deserialize(bytes).unwrap();
    deserialize
}

pub fn get_hash(value: &[u8]) -> String {
    let mut hasher = Sha3::sha3_256();
    hasher.input(value);
    hasher.result_str()
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
struct Point {
    x: i32,
    y: i32,
}


#[cfg(test)]
mod tests {
    use crate::coder::Point;
    use crate::coder::{my_serialize, my_deserialize};
    use crate::coder::get_hash;

    #[test]
    fn coders_works() {
        let point = Point { x: 1, y: 1 };
        let se = my_serialize(&point);
        let de: Point = my_deserialize(&se);
        assert_eq!(de, point);
    }

    #[test]
    fn hasher() {
        let str = "123".to_string();
        let str_hash = get_hash(&str.as_bytes());
        println!("{}", str_hash);
    }
}

